const { network, ethers } = require("hardhat");
const { parseEther } = require("ethers"); // ethers v6
const { networkConfig, developmentChains } = require("../helper-hardhat-config");
const { verify } = require("../utils/verify");
const { extractEventArg } = require("../utils/extractEventArg");
 
const VRF_SUB_FUND_AMOUNT = parseEther("30"); // 30 LINK

module.exports = async ({ deployments, getNamedAccounts }) => {
    const { deploy, log } = deployments;
    const { deployer } = await getNamedAccounts();
    const chainId = network.config.chainId;

    let vrfCoordinatorV2PlusAddress, subscriptionId;
    if (chainId == 31337) {
        // get the mock contract address
        const deployment = await deployments.get("VRFCoordinatorV2_5Mock");
        vrfCoordinatorV2PlusAddress = deployment.address;
        console.log(`Deployed mock contract to: ${vrfCoordinatorV2PlusAddress}`);

        // use ethers v6 to get the contract instance
        const vrfCoordinatorV2PlusMockContract = await ethers.getContractAt(
            "VRFCoordinatorV2_5Mock",   
            vrfCoordinatorV2PlusAddress
        );

        // create a subscription
        const transactionResponse = await vrfCoordinatorV2PlusMockContract.createSubscription();
        const transactionReceipt = await transactionResponse.wait();

        // subscriptionId = transactionReceipt.events[0].args.subId; // ethers v5
        // analyze the transaction receipt to get the subscription ID for ethers v6
        const subscriptionIds = extractEventArg(transactionReceipt, vrfCoordinatorV2PlusMockContract, "SubscriptionCreated", "subId");
        subscriptionId = subscriptionIds[0]; // get the first subscription ID
        console.log(`Subscription created with ID: ${subscriptionId}`);

        // Fund the subscription
        // Usually, you'd need the LINK token on a real network, but on a local network, you can use the mock LINK token
        await vrfCoordinatorV2PlusMockContract.fundSubscription(subscriptionId, VRF_SUB_FUND_AMOUNT);
    } else {
        subscriptionId = networkConfig[chainId]["subscriptionId"];
        vrfCoordinatorV2PlusAddress = networkConfig[chainId]["vrfCoordinatorV2Plus"];
    }
    const entranceFee = networkConfig[chainId]["raffleEntranceFee"];
    const gasLane = networkConfig[chainId]["gasLane"];
    const callbackGasLimit = networkConfig[chainId]["callbackGasLimit"];
    const updateInterval = networkConfig[chainId]["keepersUpdateInterval"];
    const enableNativePayment = false;        
    const args = [
        vrfCoordinatorV2PlusAddress,
        entranceFee,
        gasLane,
        callbackGasLimit,
        subscriptionId,
        updateInterval,
        enableNativePayment,
    ];

    log("----------------------------------------------------")
    log("Deploying Raffle and waiting for confirmations...")
    const raffle = await deploy("Raffle", {
        from: deployer,
        // gasLimit: 4000000,
        args: args,
        log: true,
        waitConformations: network.config.blockConfirmations || 1,
    })
    log(`Raffle deployed at ${raffle.address}`)

     // Ensure the Raffle contract is a valid consumer of the VRFCoordinatorV2_5Mock contract.
     if (developmentChains.includes(network.name)) {
        // const vrfCoordinatorV2PlusMockContract = await ethers.getContract("VRFCoordinatorV2_5Mock", deployer); // use deployer signer to interact with the mock contract
        // get ths signer of the deployer account
        const signer = await ethers.getSigner(deployer);
        const vrfCoordinatorV2PlusMockContract = await ethers.getContractAt(
            "VRFCoordinatorV2_5Mock",   
            vrfCoordinatorV2PlusAddress,
            signer // use deployer signer to interact with the mock contract
        );
        // Add the Raffle contract as a consumer of the VRFCoordinatorV2_5Mock contract
        await vrfCoordinatorV2PlusMockContract.addConsumer(subscriptionId, raffle.address);
        log("Consumer added to VRF Coordinator");
     }
    
    // if we are on a live network, we want to verify the contract
    if (
        !developmentChains.includes(network.name) &&
        process.env.ETHERSCAN_API_KEY
    ) {
        await verify(raffle.address, args)
    }

    log("Enter lottery with command:")
    const networkName = network.name == "hardhat" ? "localhost" : network.name
    log(`yarn hardhat run scripts/enterRaffle.js --network ${networkName}`)
    log("----------------------------------------------------")
}

module.exports.tags = ["all", "raffle"]
